<?php
namespace Game\Models\Client;

use Game\Lib\CodeConst;
use Game\Module\Tools;
use GatewayWorker\Lib\Gateway;
use Game\Models\PublicModel;
use Game\Lib\GlobalConst;
use Game\Lib\RedisConst;
use Game\Lib\Game;
use Game\Lib\OptConst;
use Game\Module\Verificate;
use Game\Config\Config;

class RoomModel extends PublicModel{

    /***************************
    common function
     ***************************/


    /*
        断线
    */
    public function userDisconnected($arrData){
        if(!isset($arrData['gaming_roomid']) || trim($arrData['gaming_roomid']) == GlobalConst::EMPTY_STRING) {
            return false;
        }
        if(!isset($arrData['account_id']) || trim($arrData['account_id']) == GlobalConst::EMPTY_STRING) {
            return false;
        }

        $room_id        = $arrData['gaming_roomid'];
        $account_id     = $arrData['account_id'];

        if($this->queryOnlineStatus($room_id, $account_id)){
            $this->writeLog("[$room_id] [$account_id] is still in room");
            return true;
        }

        $this->writeLog("[$room_id] ($account_id) 离线");

        //获取房间状态
        $room_status = $this->queryRoomStatus($room_id);
        if($room_status === RedisConst::DATA_NONEXISTENT || $room_status == Game::RoomStatus_Closed ){ //房间已经废弃或未激活
            return true;
        }

        //没开局玩过的用户离线，自动从房间中退出
        $flag = $this->leaveSeatTransaction($room_id,$account_id);
        if(2 == $flag){         //unchecked 离座
            $account_status = Game::AccountStatus_Initial;
        } else if(1 == $flag){  //checked 离座
            $account_status = $this->queryAccountStatus($room_id, $account_id);
            if($account_status == Game::AccountStatus_Ready){   //准备状态下断线， 变为未准备
                $account_status = Game::AccountStatus_Notready;
            }
        } else {
            $account_status = Game::AccountStatus_Initial;
        }

        $this->updateAccountStatus($room_id, $account_id, $account_status );

        $this->lremRoomGuestKey($room_id,0,$account_id);
        if($room_status == Game::RoomStatus_Waiting){
            $ready_count = $this->queryReadyCount($room_id);
            if($ready_count < 2){
                //取消倒计时
                $this->deleteRoomTimer($room_id);
                $arr = array("result"=>0,"operation"=>"CancelStartLimitTime","data"=>array(),"result_message"=>"取消开局倒计时");
                $this->pushMessageToGroup($room_id, $arr);
            } else {
                $this->startGame($room_id);
            }
        }

        //判断是否全部人离线
        $clients_of_groupid = Gateway::getClientSessionsByGroup($room_id);
        if(count($clients_of_groupid) == 0) {
            $this->setupClearRoomPassiveTimer($room_id);
        }

        return true;
    }



    /***************************
    logic function
     ***************************/

    /**
     * 创建房间
     * @param $arrData
     * @return array
     */
    public function createRoom($arrData){
        $timestamp = time();
        $result = array();
        $data  = $arrData["data"];
        $account_id = $arrData["account_id"];
        $session = $arrData["session"];
        $operation = $arrData["operation"];

        if(false == Verificate::getInstance()->checkRequestSession($account_id,$session)){
            return array("result"=>CodeConst::Check_Session_Failed,"operation"=>$operation,"data"=>array(),"result_message"=>"玩家登录失效");
        }
        //底分
        if(!isset($data['default_score']) || !in_array($data['default_score'], [2,4,8,10,25,20,50]) ) {
            $this->logMessage('error', "function(createRoom):lack of default_score"." in file".__FILE__." on Line ".__LINE__);
            return $this->_missingPrameterArr($operation,"default_score");
        }
        if(!isset($data['data_key']) || trim($data['data_key']) == GlobalConst::EMPTY_STRING) {
            $this->logMessage('error', "function(createRoom):lack of data_key"." in file".__FILE__." on Line ".__LINE__);
            return $this->_missingPrameterArr($operation,"data_key");
        }

        if(!isset($data['chip_type'])) {
            $this->logMessage('error', "function(createRoom):lack of chip_type"." in file".__FILE__." on Line ".__LINE__);
            return $this->_missingPrameterArr($operation,"chip_type");
        }
        if(!isset($data['disable_pk_score'])) {
            $this->logMessage('error', "function(createRoom):lack of disable_pk_score"." in file".__FILE__." on Line ".__LINE__);
            return $this->_missingPrameterArr($operation,"disable_pk_score");
        }
        if(!isset($data['disable_pk_men'])) {
            $this->logMessage('error', "function(createRoom):lack of disable_pk_men"." in file".__FILE__." on Line ".__LINE__);
            return $this->_missingPrameterArr($operation,"disable_pk_men");
        }
        if(!isset($data['upper_limit']) || !in_array($data['upper_limit'], [0,500,1000,2000]) ) {
            $this->logMessage('error', "function(createRoom):lack of upper_limit"." in file".__FILE__." on Line ".__LINE__);
            return $this->_missingPrameterArr($operation,"upper_limit");
        }
        if(!isset($data['maxplayer_count']) || !in_array($data['maxplayer_count'], [6,9,12]) ) {
            $this->logMessage('error', "function(createRoom):lack of maxplayer_count"." in file".__FILE__." on Line ".__LINE__);
            return $this->_missingPrameterArr($operation,"maxplayer_count");
        }
        if(!isset($data['totalgame_set']) || !in_array($data['totalgame_set'], [12,24]) ) {
            $this->logMessage('error', "function(createRoom):lack of totalgame_set"." in file".__FILE__." on Line ".__LINE__);
            return $this->_missingPrameterArr($operation,"totalgame_set");
        }
        if(!isset($data['xipai_score'])){
            $this->logMessage('error', "function(createRoom):lack of xipai_score"." in file".__FILE__." on Line ".__LINE__);
            return $this->_missingPrameterArr($operation,"xipai_score");
//            $data['xipai_score'] = 0;
        }
        if(!isset($data['disable_look'])){
            $this->logMessage('error', "function(createRoom):lack of disable_look"." in file".__FILE__." on Line ".__LINE__);
            return $this->_missingPrameterArr($operation,"disable_look");
//            $data['disable_look'] = 0;
        }
        if(!isset($data['client_name'])){
            $data['client_name'] = "wechat";
        }
        if(!isset($data['client_type'])){
            $data['client_type'] = "wechat";
        }



        //获取维护公告
//        $announcement_result = $this->getGameAnnouncement($account_id);
//        if(is_array($announcement_result) && $announcement_result['alert_type'] == 4) {
//            $result['alert_type'] = $announcement_result['alert_type'];
//            return array("result"=>"-1","operation"=>$operation,"data"=>$result,"result_message"=>$announcement_result['alert_text']);
//        }

        //判断房卡余额
        $my_ticket_count = $this->getTicketCount($account_id);
        $this->writeLog("($account_id) 房卡:" . $my_ticket_count);
        //获取房卡消耗
        $spend_ticket_count = $this->getTicketUse($data);
        if($my_ticket_count < $spend_ticket_count || $spend_ticket_count === -1){
            $this->writeLog("($account_id) 房卡不足");
            return array("result"=>CodeConst::Ticket_Not_Enough,"operation"=>$operation,"data"=>["alert_type"=>1],"result_message"=>"房卡不足");
        }

        //判断房间申请记录是否存在
        $room_info = $this->getRoomByDataKey($data['data_key']);
        if(!is_array($room_info) || count($room_info) == 0 ) {
            //获取随机房间密码
            $room_password = $this->getRoomPassword();
            $is_close = GlobalConst::IS_FALSE;

            $r_array['create_time'] = $timestamp;
            $r_array['update_time'] = $timestamp;
            $r_array['is_deleted'] = GlobalConst::IS_FALSE;
            $r_array['data_key'] = $data['data_key'];
            $r_array['creator_id'] = $account_id;
            $r_array['ticket_creator_id'] = $account_id;
            $r_array['is_close'] = GlobalConst::IS_FALSE;
            $r_array['game_type'] = Game::Game_Type;
            $r_array['room_password'] = $room_password;
            $r_array['client_name'] = $data['client_name'];
            $r_array['client_type'] = $data['client_type'];
            $room_id = $this->insertRoom($r_array);
            if($room_id > 0) {
                $room_number = 100000 + $room_id * 10 + mt_rand(1,9);
                $this->updateRoom($room_id,["room_number"=>$room_number]);
            } else {
                $this->logMessage('error', "function(createRoom):用户".$account_id." 创建房间失败："." in file".__FILE__." on Line ".__LINE__);
                return array("result"=>CodeConst::Room_Create_Failed,"operation"=>$operation,"data"=>["alert_type"=>1],"result_message"=>"创建房间失败");
            }
        } else {
            $room_id = $room_info['id'];
            $room_number = $room_info['room_number'];
            $is_close = $room_info['is_close'];
            $room_password = $room_info['room_password'];
        }
        //添加房间信息到redis
        $r_mkv[RedisConst::Room_Field_Number]         = $room_number;         // 房间号
        $r_mkv[RedisConst::Room_Field_CurrentGameSet] = 0; // 当前局数
        $r_mkv[RedisConst::Room_Field_TotalGameSet]   = $data['totalgame_set'];   // 每轮总局数
        $r_mkv[RedisConst::Room_Field_Status]         = Game::RoomStatus_Waiting;         // 房间状态，1等待、2进行中、3关闭
        $r_mkv[RedisConst::Room_Field_DefaultScore]   = $data['default_score'];   // 开局默认分数
        $r_mkv[RedisConst::Room_Field_Banker]         = 0;         // 庄家 account_id
        $r_mkv[RedisConst::Room_Field_Scoreboard]     = "{}";     // 每局积分榜
        $r_mkv[RedisConst::Room_Field_Creator]        = $account_id;        // 房间创建者 account_id
        $r_mkv[RedisConst::Room_Field_TicketCount]    = $spend_ticket_count;    // 每轮消耗房卡数量 1   2
        $r_mkv[RedisConst::Room_Field_ChipType]       = $data["chip_type"];       // 筹码组  1   2
        $r_mkv[RedisConst::Room_Field_DisablePkScore] = $data["disable_pk_score"];     // 不能比牌
        $r_mkv[RedisConst::Room_Field_DisablePkMen]   = $data["disable_pk_men"];       // 不能比牌
        $r_mkv[RedisConst::Room_Field_DisableLook]    = $data["disable_look"];        // 首轮不能看牌
        $r_mkv[RedisConst::Room_Field_UpperLimit]     = $data["upper_limit"];     // 封顶上限
        $r_mkv[RedisConst::Room_Field_XiPaiScore]     = $data["xipai_score"];     // 喜牌
        $r_mkv[RedisConst::Room_Field_StartTime]      = 0;      // 开局时间
        $r_mkv[RedisConst::Room_Field_Onlybig]        = $data["only_big"];        // 只发AKQJ10
        $r_mkv[RedisConst::Room_Field_Password]       = $room_password;       // 房间密码.
        $r_mkv[RedisConst::Room_Field_PlayerCount]    = 0;    // 玩家数量.
        $r_mkv[RedisConst::Room_Field_MaxPlayerCount] = $data["maxplayer_count"]; // 最大玩家数量.


        $this->updateRoomKey($room_id, $r_mkv);
        $this->updateRoomPasswordKey($room_password,json_encode(["room_number"=>$room_number,"game_type"=>Game::Game_Type, "create_time"=>date('Y-m-d H:i:s',$timestamp),"client_name"=>$data['client_name']]));
        $result['room_id'] = $room_id;
        $result['room_number'] = $room_number;
        $result['is_close'] = $is_close;

        //扣除房卡
        $this->balanceTicket($room_id, $account_id, $spend_ticket_count);

        //观战功能 建房时设定清房定时器
        $this->setupClearRoomPassiveTimer($room_id);
        $this->writeLog("[$room_id] ($account_id) 创建房间".$room_number);
        return array("result"=>CodeConst::Room_Create_Success,"operation"=>$operation,"data"=>$result,"result_message"=>"创建房间");
    }


    /**
     * 进房之前的查询
     * @param $arrData
     * @return array
     */
    public function prepareJoinRoom($arrData){
        $result = array();
        $data           = $arrData['data'];
        $operation      = $arrData['operation'];
        $account_id     = $arrData['account_id'];
        $room_number    = $arrData['room_number'];
        $session        = $arrData['session'];


        if(false == Verificate::getInstance()->checkRequestSession($account_id,$session)) {
            return array("result"=>CodeConst::Check_Session_Failed,"operation"=>$operation,"data"=>array(),"result_message"=>"玩家登录失效");
        }


        //判断房间是否存在
        $room_row= $this->getRoomByRoomNumber($room_number);
        if(!$room_row){
            $this->logMessage('error', "function(joinRoom):room(".$room_number.") not exist"." in file".__FILE__." on Line ".__LINE__);
            return array("result"=>OptConst::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"房间不存在");
        } else {
            if($room_row['is_close']){
                $result = array('room_status'=>4);
                return array("result"=>0, "operation"=>$operation,"data"=>$result,"result_message"=>"房间已关闭");
            }
        }
        //房间参数
        $user_count = 0;
        $room_array = $this->queryRoomKey($room_row['id']);
        //房间人
        $room_users = array();
        $is_member = false;
        //获取房间所有用户
        $gamer_query = $this->queryRoomMembers($room_row['id']);

        if(count($gamer_query)>0) {
            $rows = $this->getAccountListByIDs($gamer_query);
            if(is_array($rows)){
                foreach ($rows as $item) {
                    $room_users[] = $item['nickname'];
                    $user_count++;
                    if($item['account_id'] == $account_id){
                        $is_member = true;
                    }
                }
            }
        }

        //观战功能
        $room_array['is_member'] = $is_member;
        $room_array['can_join'] = $user_count < $room_array[RedisConst::Room_Field_MaxPlayerCount];
        $room_array['room_users'] = $room_users;
        return array("result"=>"0","operation"=>$operation,"data"=>$room_array,"result_message"=>"进房询问");
    }







    /*
        进入房间
    */
    public function joinRoom($arrData){
        $data           = $arrData['data'];
        $operation      = $arrData['operation'];
        $account_id     = $arrData['account_id'];
        $client_id      = $arrData['client_id'];
        $room_number    = $arrData['room_number'];

        $session        = $arrData['session'];
        if(false == Verificate::getInstance()->checkRequestSession($account_id,$session)) {
            return array("result"=>CodeConst::Check_Session_Failed,"operation"=>$operation,"data"=>array(),"result_message"=>"玩家登录失效");
        }


        //判断房间是否存在
        $room_row = $this->getRoomByRoomNumber($room_number);
        if(!$room_row){
            $this->logMessage('error', "function(joinRoom):room(".$room_number.") not exist"." in file".__FILE__." on Line ".__LINE__);
            return array("result"=>OptConst::FAILED,"operation"=>$operation,"data"=>array(),"result_message"=>"房间不存在");
        } else {
            $room_id = $room_row['id'];
            if($room_row['is_close']){
                return array("result"=>0, "operation"=>$operation,"data"=>array('room_status'=>4),"result_message"=>"房间已关闭");
            }
        }

        //判断用户是否已加入房间
        $seat_num = $this->querySeatNumber($room_id, $account_id);
        if($seat_num > 0) {
            //获取分数
            $player_score = $this->queryRoomScoreKey($room_id,$account_id);
            $account_status = $this->queryAccountStatus($room_id, $account_id);
        } else {
            $seat_num = $this->joinRoomTransaction($room_id,$account_id, Config::GameUser_MaxCount);
            if(!$seat_num){
                return array("result"=>1,"operation"=>$operation,"data"=>array('alert_type' => 2),"result_message"=>"房间人数已满");
            }
            //添加默认分数
            $player_score = 0;
            $player_score_mkv[$account_id] = $player_score;
            $this->updateRoomScoreKey($room_id, $player_score_mkv);
            //首次进房初始状态
            $mkv[$account_id] = Game::AccountStatus_Initial;
            $this->updateAccountStatusKey($room_id, $mkv);
        }
        $replyArr = array("[roomid]"=>$room_id,"[accountid]"=>$account_id);
        //绑定用户UID
        $RoomUser_UID = strtr(Game::RoomUser_UID, $replyArr);
        Gateway::bindUid($client_id, $RoomUser_UID);
        Gateway::joinGroup($client_id, $room_id);

        //获取房间当前局数
        $game_num = $this->queryGameNumber($room_id);
        $room_status = $this->queryRoomStatus($room_id);
        $room_ary['room_id'] = $room_id;
        $room_ary['room_number'] = $room_number;
        $room_ary['room_status'] = $room_status;
        $room_ary['account_score'] = $player_score;
        $room_ary['account_status'] = $account_status;
        $room_ary['online_status'] = $this->queryOnlineStatus($room_id, $account_id);

        $room_ary['serial_num'] = $seat_num;
        $room_ary['game_num'] = $game_num;
        $room_ary['total_num'] = $this->queryTotalNum($room_id);

        $room_ary['ticket_checked'] = $this->queryTicketChecked($room_id, $account_id);
        $room_ary['scoreboard'] = $this->queryScoreboard($room_id);

        $card_info = array();
        $card_type = 0;
        if($this->querySeenCard($room_id, $account_id)){    //已经看过牌的
            $card_info = $this->queryCardInfo($room_id, $account_id);
            $value = $this->caculateCardValue($room_id, $account_id);
            $card_type = substr($value, 0, 1);
        }

        $room_ary['cards'] = $card_info;
        $room_ary['card_type'] = $card_type;

        $room_ary['benchmark'] = $this->queryBenchmark($room_id);
        $room_ary['pool_score'] = $this->queryPoolScore($room_id);



        $setting = $this->queryRoomKey($room_id);
        $room_ary['ticket_count'] =isset($setting[RedisConst::Room_Field_TicketCount]) ?$setting[RedisConst::Room_Field_TicketCount]:1;
        $room_ary['chip_type'] = isset($setting[RedisConst::Room_Field_ChipType])?$setting[RedisConst::Room_Field_ChipType]:1;
        $room_ary['disable_pk_100'] =isset($setting[RedisConst::Room_Field_DisablePk100]) ?$setting[RedisConst::Room_Field_DisablePk100]:0;
        $room_ary['disable_look'] =isset($setting[RedisConst::Room_Field_DisableLook]) ?$setting[RedisConst::Room_Field_DisableLook]:0;

        $room_ary['disable_pk_men'] =isset($setting[RedisConst::Room_Field_DisablePkMen]) ?$setting[RedisConst::Room_Field_DisablePkMen]:0;
        $room_ary['upper_limit'] =isset($setting[RedisConst::Room_Field_UpperLimit]) ?$setting[RedisConst::Room_Field_UpperLimit]:1000;

        $room_ary['xipai_score']    = $setting[RedisConst::Room_Field_XiPai];
        //推送房间信息
        $room_return = array("result"=>OptConst::SUCCESS,"operation"=>$operation,"data"=>$room_ary,"result_message"=>"入房成功");
        $this->pushMessageToCurrentClient($room_return);

        //返回所有玩家状态给进房玩家
        $allGamer = $this->getGamerInfo($room_id);
        if(is_array($allGamer))
        {
            $currentGamer_return = array("result"=>OptConst::SUCCESS,"operation"=>"AllGamerInfo","data"=>$allGamer,"result_message"=>"所有玩家状态");
            $this->pushMessageToCurrentClient($currentGamer_return);
        }

        $this->notyfyPlayingStatus($room_id, $account_id);

        //观战功能  从观战列表删除
        $this->lremRoomGuestKey($room_id, 0,$account_id);
        //返回所有观战者给当前玩家
        $allGuest = $this->getGuestInfo($room_id);
        if(is_array($allGuest))
        {
            $currentGamer_return = array("result"=>OptConst::SUCCESS,"operation"=>"AllGuestInfo","data"=>$allGuest,"result_message"=>"所有观战者状态");
            $this->pushMessageToCurrentClient($currentGamer_return);
        }

        //推送当前玩家状态给其他玩家
        $currentGamer = $this->getGamerInfo($room_id,$account_id);
        if(is_array($currentGamer))
        {
            $currentGamer_return = array("result"=>OptConst::SUCCESS,"operation"=>"UpdateGamerInfo","data"=>$currentGamer,"result_message"=>"某玩家状态");
            $this->pushMessageToGroup($room_id, $currentGamer_return, $client_id);
        }

        //显示房间目前的倒计时
        $limit = $game_num > 0 ? Game::LimitTime_Ready : Game::LimitTime_StartGame;

        if($room_status == Game::RoomStatus_Waiting && ($countdown = $this->queryCountdown($room_id, $limit)) > 0){
            $arr = array("result"=>0,"operation"=>"StartLimitTime","data"=>array('limit_time' => $countdown),"result_message"=>"开始倒计时");
            $this->pushMessageToCurrentClient($arr);
        }

        //保存用户当前房间,用户ID
        $_SESSION['gaming_roomid'] = $room_id;
        $_SESSION['account_id'] = $account_id;

        $this->writeLog("[$room_id] $account_id 进入房间");
        return OptConst::NO_RETURN;
    }

    protected function notyfyPlayingStatus($room_id, $account_id)
    {
        $active_user =  $this->queryActiveUser($room_id);
        if($active_user != -1){
            $can_open = 0;
            $pk_user = array();
            if($this->pkChipConditon($room_id, $active_user)){
                $pk_user = $this->queryPkUser($room_id, $active_user);
                if(count($pk_user) > 0){
                    $can_open = 1;
                }
            }

            //通知:哪位正进行下注
            $noty_arr = array(
                'account_id' => $active_user,
                'playing_status' => Game::PlayingStatus_Betting,
                'limit_time'     => $this->queryCountdown($room_id, Game::LimitTime_Betting),
                'can_open' => $can_open,
                'pk_user' => $pk_user ,
                'can_look' => $this->lookConditon($room_id, $active_user)
            );
            $msg_arr = array("result"=>0,"operation"=>"NotyChooseChip","data"=>$noty_arr,"result_message"=>"通知下注");
            $this->pushMessageToCurrentClient($msg_arr);
        }
    }

    /*
        观战功能 进入观战
    */
    public function guestRoom($arrData)
    {
        $timestamp = time();
        $result = array();
        $return = array();

        $data           = $arrData['data'];
        $operation      = $arrData['operation'];
        $account_id     = $arrData['account_id'];
        $client_id      = $arrData['client_id'];

        $session        = $arrData['session'];

        if(false == Verificate::getInstance()->checkRequestSession($account_id,$session))
        {
            return OptConst::NO_RETURN;
        }

        if(!(isset($room_number)&& $room_number > 0) )
        {
            $this->writeLog(__FUNCTION__.":lack of room_number"." in file".__FILE__." on Line ".__LINE__);
            return $this->_missingPrameterArr($operation,"room_number");
        }

        $room_number = $room_number;

        //判断房间是否存在
        $room_row = $this->getRoomByRoomNumber($room_number);
        if(!$room_row){
            $this->writeLog(__FUNCTION__.":room($room_number) not exist"." in file".__FILE__." on Line ".__LINE__);
            return array("result"=>OptConst::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"房间不存在");
        } else {
            $room_id = $room_row['room_id'];
            if($room_row['is_close']){
                $result = array('room_status'=>4);
                return array("result"=>0, "operation"=>$operation,"data"=>$result,"result_message"=>"房间已关闭");
            }
        }


        $guests = $this->lrangeRoomGuestKey($room_id);
        //判断用户是否已加入观战
        if(!in_array($account_id, $guests)){
            $this->pushRoomGuestKeyList($room_id,[$account_id],1,0);
        }

        //绑定用户UID
        $RoomUser_UID = strtr(Game::RoomUser_UID, array("[roomid]"=>$room_id,"[accountid]"=>$account_id));
        Gateway::bindUid($client_id, $RoomUser_UID);
        Gateway::joinGroup($client_id, $room_id);

        //获取房间当前局数
        $setting = $this->queryRoomKey($room_id);
        $game_num = $setting[RedisConst::Room_Field_GameNum];
        $total_num = $setting[RedisConst::Room_Field_TotalNum];
        $room_status = $setting[RedisConst::Room_Field_Status];
        $scoreboard_str = $setting[RedisConst::Room_Field_Scoreboard];
        $scoreboard = json_decode($scoreboard_str);


        $room_ary['room_id'] = $room_id;
        $room_ary['room_status'] = $room_status;
        $room_ary['game_num'] = $game_num;
        $room_ary['total_num'] = $total_num;
        $room_ary['scoreboard'] = $scoreboard;

        $room_ary['benchmark'] = $this->queryBenchmark($room_id);
        $room_ary['pool_score'] = $this->queryPoolScore($room_id);

        //推送房间信息
        $room_return = array("result"=>OptConst::SUCCESS,"operation"=>$operation,"data"=>$room_ary,"result_message"=>"入房成功");
        $this->pushMessageToCurrentClient($room_return);

        //在座->观战
        $try_start = false;
        $flag = $this->leaveSeatTransaction($room_id,$account_id);
        if($flag > 0){
            $try_start = true;
            $this->writeLog("[$room_id] ($account_id) 玩家变为观战者");
        }

        //返回所有玩家状态给当前玩家
        $allGamer = $this->getGamerInfo($room_id);
        if(is_array($allGamer))
        {
            $currentGamer_return = array("result"=>OptConst::SUCCESS,"operation"=>"AllGamerInfo","data"=>$allGamer,"result_message"=>"所有玩家状态");
            $this->pushMessageToCurrentClient($currentGamer_return);
        }

        $this->notyfyPlayingStatus($room_id, $account_id);

        //返回所有观战者给当前玩家
        $allGuest = $this->getGuestInfo($room_id);
        if(is_array($allGuest))
        {
            $currentGamer_return = array("result"=>OptConst::SUCCESS,"operation"=>"AllGuestInfo","data"=>$allGuest,"result_message"=>"所有观战者状态");
            $this->pushMessageToCurrentClient($currentGamer_return);
        }

        //推送当前观战者给其他玩家
        $row = $this->getAccountByID($account_id);
        if($row){
            $guest = array(
                'account_id' => $account_id,
                'nickname'   => $row['nickname'],
                'headimgurl' => $row['headimgurl'],
                'is_guest'   => "1"
            );
            $guest_return = array("result"=>OptConst::SUCCESS,"operation"=>"UpdateGuestInfo","data"=>$guest,"result_message"=>"某观战者状态");
            $this->pushMessageToGroup($room_id, $guest_return, $client_id);
        } else {
            $this->writeLog("推送当前观战者:account($account_id) not exist".__FILE__.__LINE__);
        }

        //显示房间目前的倒计时
        $limit = $game_num > 0 ? Game::LimitTime_Ready : Game::LimitTime_StartGame;
        if($room_status == Game::RoomStatus_Waiting && ($countdown = $this->queryCountdown($room_id, $limit)) > 0){
            $arr = array("result"=>0,"operation"=>"StartLimitTime","data"=>array('limit_time' => $countdown),"result_message"=>"开始倒计时");
            $this->pushMessageToCurrentClient($arr);
        }

        //保存用户当前房间,用户ID
        $_SESSION['gaming_roomid'] = $room_id;
        $_SESSION['account_id'] = $account_id;

        if($try_start){
            $this->startGame($room_id);
        }

        $this->writeLog("[$room_id] ($account_id) 观战");
        return OptConst::NO_RETURN;
    }
    /*
        获取观战者
    */
    protected function getGuestInfo($room_id) {
        $result = array();
        //观战者列表
        $guests = $this->lrangeRoomGuestKey($room_id);

        if(count($guests)>0){
            $rows = $this->getAccountListByIDs($guests);
            if(is_array($rows)){
                foreach ($rows as $item) {
                    $info['account_id'] = $item['account_id'];
                    $info['nickname'] = $item['nickname'];
                    $info['headimgurl'] = $item['headimgurl'];
                    $result[] = $info;
                }
            }
        }
        return $result;
    }

    /*
        拉取房间信息
    */
    public function pullRoomInfo($arrData)
    {
        $result = array();

        $data           = $arrData['data'];
        $operation      = $arrData['operation'];
        $account_id     = $arrData['account_id'];
        $client_id      = $arrData['client_id'];

        $session        = $arrData['session'];

        if(false == Verificate::getInstance()->checkRequestSession($account_id,$session)) {
            return OptConst::NO_RETURN;
        }

        if(!(isset($data['room_id'])&& $data['room_id'] > 0) ) {
            $this->logMessage('error', "function(pullRoomInfo):lack of room_id"." in file".__FILE__." on Line ".__LINE__);
            return $this->_missingPrameterArr($operation,"room_id");
        }

        $room_id = $data['room_id'];

        $is_legal = $this->checkRequestClientLegal($client_id,$room_id,$account_id);
        if(!$is_legal) {
            $this->logMessage('error', "function(checkRequestClientLegal):illegal opt: account_id($account_id) room_id($room_id)"." in file".__FILE__." on Line ".__LINE__);
            //推送强制下线
            $illegal_message = Tools::getInstance()->jsonEncode(array("result"=>"-203","result_message"=>"illegal opt"));
            Gateway::sendToCurrentClient($illegal_message);
            return OptConst::NO_RETURN;
        }

        //判断用户是否已加入房间
        $serial_num = $this->querySerialNum($room_id, $account_id);
        if($serial_num > 0){     //已加入
            //获取分数
            $rScore_score = $this->queryRoomScoreKey($room_id, $account_id);
            $account_status = $this->queryAccountStatus($room_id, $account_id);
        } else {    //未加入
            $this->logMessage('error', "function(pullRoomInfo):account($account_id) not join room"." in file".__FILE__." on Line ".__LINE__);
            return array("result"=>OptConst::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"用户未加入房间");
        }

        $room_ary['account_score'] = $rScore_score;
        $room_ary['account_status'] = $account_status;
        $room_ary['online_status'] = $this->queryOnlineStatus($room_id, $account_id);

        $room_ary['serial_num'] = $serial_num;

        $room_ary['ticket_checked'] = $this->queryTicketChecked($room_id, $account_id);

        $card_info = array();
        $card_type = 0;
        if($this->querySeenCard($room_id, $account_id)){    //已经看过牌的
            $card_info = $this->queryCardInfo($room_id, $account_id);
            $value = $this->caculateCardValue($room_id, $account_id);
            $card_type = substr($value, 0, 1);
        }

        $room_ary['cards'] = $card_info;
        $room_ary['card_type'] = $card_type;

        $room_ary['benchmark'] = $this->queryBenchmark($room_id);
        $room_ary['pool_score'] = $this->queryPoolScore($room_id);

        $setting = $this->queryRoomKey($room_id);
        $room_ary['chip_type'] = isset($setting[RedisConst::Room_Field_ChipType])?$setting[RedisConst::Room_Field_ChipType]:1;

        //返回所有玩家状态
        $allGamer = $this->getGamerInfo($room_id);
        if(!is_array($allGamer)) {
            $this->logMessage('error', "function(pullRoomInfo):room($room_id) no player"." in file".__FILE__." on Line ".__LINE__);
            return array("result"=>OptConst::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"房间没有其他用户");
        }

        $pull_return = array("result"=>OptConst::SUCCESS,"operation"=>$operation,"data"=>$room_ary,"result_message"=>"拉取房间信息","all_gamer_info"=>$allGamer);

        $this->pushMessageToCurrentClient($pull_return);

        $this->notyfyPlayingStatus($room_id, $account_id);

        $this->logMessage('error', "function(pullRoomInfo):用户$account_id 拉取房间$room_id 信息"." in file".__FILE__." on Line ".__LINE__);
        $this->logMessage('error', "function(pullRoomInfo):pull_return:".json_encode($pull_return). " in file".__FILE__." on Line ".__LINE__);

        return OptConst::NO_RETURN;
    }

    /**
     * 获取房间所有用户
     * @param $room_id
     * @param int $account_id
     * @return array|bool
     */
    protected function getGamerInfo($room_id,$account_id=-1)
    {
        $result = array();
        //获取房间所有用户
        $gamer_query = $this->queryRoomMembers($room_id, true);
        if(count($gamer_query) > 0) {
            foreach($gamer_query as $gamer_id=>$serial_num)
            {
                //获取玩家信息
                $account_query = $this->getAccountByID($gamer_id);
                if(!is_array($account_query)) {
                    $this->logMessage('error', "function(getGamerInfo):account($gamer_id) not exist"." in file".__FILE__." on Line ".__LINE__);
                    return false;
                }
                $info['serial_num'] = $serial_num;
                $info['account_id'] = $gamer_id;
                $info['nickname'] = $account_query['nickname'];
                $info['headimgurl'] = $account_query['headimgurl'];


                //获取玩家当前积分
                $rScore_score = $this->queryRoomScoreKey($room_id, $gamer_id);
                if(RedisConst::DATA_NONEXISTENT === $rScore_score) {
                    $this->logMessage('error', "function(getGamerInfo):account($gamer_id) score not exist"." in file".__FILE__." on Line ".__LINE__);
                    return false;
                }
                $info['account_score'] = $rScore_score;

                //获取玩家当前状态
                $rStatus = $this->queryAccountStatus($room_id, $gamer_id);
                if(RedisConst::DATA_NONEXISTENT === $rStatus) {
                    $this->logMessage('error', "function(getGamerInfo):account($gamer_id) status not exist"." in file".__FILE__." on Line ".__LINE__);
                    return false;
                }
                $info['account_status'] = $rStatus;
                $info['online_status'] = $this->queryOnlineStatus($room_id, $gamer_id);
                $info['ticket_checked'] = $this->queryTicketChecked($room_id, $gamer_id);

                if($account_id == $gamer_id) {
                    return $info;
                }

                $result[] = $info;

            }
        }

        return $result;
    }

    //开局
    protected function startGame($room_id, $passive_by_timer=false){
        $ready_user = $this->queryReadyUser($room_id);
        $in_room_array = $this->queryInRoomUser($room_id);
        $ready_count = count($ready_user);
        $online_count = count($in_room_array);

        //准备人数 大于等于2 且 准备人数 等于 在线人数
        $this->writeLog("[$room_id] 准备:".$ready_count."人   "."在线:".$online_count."人");

        if($ready_count >=2) {
            if($passive_by_timer || $ready_count == $online_count){

                $pre_readyUser_ary = array();       //已准备用户数组-前
                $rear_readyUser_ary = array();      //已准备用户数组-后
                $is_rear = true;

                $ready_in_room_user = array_intersect($in_room_array, $ready_user); //在房的已准备用户
                if(count($ready_in_room_user) < 2){
                    $this->writeLog("在房".$room_id."的已准备用户数量:".count($ready_in_room_user)." 不能开局 in file".__FILE__." on Line ".__LINE__);
                    return false;
                }

                $success = $this->setRoomStatusTransaction($room_id, 1, 2);
                if(!$success){
                    $this->writeLog("并发 start game，忽略。room id:".$room_id."。in file".__FILE__." on Line ".__LINE__);
                    return false;
                }

                //开始游戏
                //参与游戏的都需要checked
                $ready_in_room_user = $this->ticketCheckTransaction($room_id, $ready_in_room_user);  //参与游戏玩家
                if(count($ready_in_room_user) < 2){ //异常情况
                    $this->setRoomStatusTransaction($room_id, 2, 1);    //修正房间状态
                    $this->writeLog("[$room_id]的参与玩家数:".count($ready_in_room_user)." 不能开局 in file".__FILE__." on Line ".__LINE__);
                    return false;
                }

                $banker_id = $this->queryBanker($room_id);

                foreach($ready_in_room_user as $account_id) {
                    if(in_array($account_id, $ready_in_room_user)) {
                        if($is_rear) {
                            $rear_readyUser_ary[] = $account_id;
                        } else {
                            $pre_readyUser_ary[] = $account_id;
                        }
                    }

                    if($account_id == $banker_id) {
                        $is_rear = false;
                    }
                }

                $readyUser_ary = array_merge($pre_readyUser_ary,$rear_readyUser_ary);
                $next_banker_id = $readyUser_ary[0];
                if(!$passive_by_timer){
                    //取消倒计时
                    $this->deleteRoomTimer($room_id);
                }

                //删除每局玩家筹码hash
                $this->deleteChipKey($room_id);
                //删除每局玩家看牌标识hash
                $this->deleteSeenCardKey($room_id);
                //删除每局玩家手牌hash
                $this->deleteCardKey($room_id);


                $cardMkv = array();
                $accountStatusMvk = array();

                $only_big = $this->queryRoomKey($room_id, RedisConst::Room_Field_Onlybig);
                $only_big = $only_big > 0 ? true : false;
                $readyUserCount = count($readyUser_ary);  //游戏中玩家数量
                $player_cards = $this->dealCard($readyUserCount,$only_big);  //发牌

                for ($i=0; $i < $readyUserCount; $i++) {
                    $account_id = $readyUser_ary[$i];
                    //玩家状态变成闷牌状态
                    $accountStatusMvk[$account_id] = Game::AccountStatus_Invisible;
                    //设置每局玩家手牌hash
                    $cardMkv[$account_id] = $player_cards[$i];
                }

                //设置每局玩家顺序list
                $play_member = $readyUser_ary;

                $this->updateCardKey($room_id,$cardMkv);
                $this->updateAccountStatusKey($room_id,$accountStatusMvk);
                //删除每局玩家顺序list 再装入本局玩家
                $this->deletePlayMemberKey($room_id);
                $this->pushPlayMemberKeyList($room_id,$play_member,0,0); //lpush
                //重设每局游戏参数
                $parameter_ary[RedisConst::Play_Field_PoolScore] = 0;// Game::Default_Score * $ready_count;
                $parameter_ary[RedisConst::Play_Field_Benchmark] = Game::Default_Score;
                $parameter_ary[RedisConst::Play_Field_ActiveUser] =  $next_banker_id;
                $this->updatePlayKey($room_id, $parameter_ary);


                $roomMkv[RedisConst::Room_Field_Status] = 2;  //房间状态，1等待、2进行中、3关闭
                $roomMkv[RedisConst::Room_Field_Banker] = $next_banker_id;
                $this->updateRoomKey($room_id, $roomMkv);

                //房间轮数与局数更新
                $this->updateGameNumberRound($room_id);
                $setting = $this->queryRoomKey($room_id);
                //底注
                foreach($readyUser_ary as $account_id)
                {
                    $this->balanceScore($room_id, $account_id, $setting[RedisConst::Room_Field_DefaultScore]);
                }

                $player_status = array();
                foreach ($play_member as $player_id) {
                    if($player_id == $next_banker_id){
                        $player_status[] = array(
                            "account_id"=> $player_id,
                            "account_status"=> Game::AccountStatus_Invisible,        //5; 初始是闷牌状态
                            "online_status" => $this->queryOnlineStatus($room_id, $player_id),
                            "playing_status"=> Game::PlayingStatus_Betting, //2;  下注中
                            "limit_time" => Game::LimitTime_Betting,
                            'can_open' =>  0,
                            'can_look' => $this->lookConditon($room_id, $player_id)
                        );
                    } else {
                        $player_status[] = array(
                            "account_id"=> $player_id,
                            "account_status"=> Game::AccountStatus_Invisible,        //5; 初始是闷牌状态
                            "online_status" => $this->queryOnlineStatus($room_id, $player_id),
                            "playing_status"=> Game::PlayingStatus_Waiting, //1 等待别人中
                            "limit_time" => 0
                        );
                    }
                }

                //设置自动弃牌定时器
                $this->setupDiscardPassiveTimer($room_id, $next_banker_id);

                //推送开始
                $arr = array("result"=>0,"operation"=>"GameStart","data"=>$player_status,"result_message"=>"游戏开始了");
                $this->pushMessageToGroup($room_id, $arr);

            } else {
                if($this->getTimerTime($room_id) == -1 ){
                    // $this->queryTimerId($room_id) == -1   只有第二个人的准备才触发倒计时   $ready_count == 2 ||

                    if($ready_count == 2){  //第二个人准备就删掉自动清理房间定时器吧
                        $this->deleteRoomTimer($room_id);
                    }

                    $this->setupStartGamePassiveTimer($room_id);
                }
            }
        }

        return true;
    }


    /*
        准备操作
    */
    public function readyStart($arrData)
    {

        $timestamp = time();
        $result = array();
        $return = array();

        $data           = $arrData['data'];
        $operation      = $arrData['operation'];
        $account_id     = $arrData['account_id'];
        $client_id      = $arrData['client_id'];

        $session        = $arrData['session'];

        if(false == Verificate::getInstance()->checkRequestSession($account_id,$session))
        {
            return OptConst::NO_RETURN;
        }

        if(!isset($data['room_id']) || trim($data['room_id']) == GlobalConst::EMPTY_STRING)
        {
            $this->logMessage('error', "function(readyStart):lack of room_id"." in file".__FILE__." on Line ".__LINE__);
            return $this->_missingPrameterArr($operation,"room_id");
        }

        $room_id = $data['room_id'];

        $is_legal = $this->checkRequestClientLegal($client_id,$room_id,$account_id);
        if(!$is_legal)
        {
            $this->logMessage('error', "function(checkRequestClientLegal):illegal opt: account_id($account_id) room_id($room_id)"." in file".__FILE__." on Line ".__LINE__);
            //推送强制下线
            $illegal_message = Tools::getInstance()->jsonEncode(array("result"=>"-203","result_message"=>"illegal opt"));
            Gateway::sendToCurrentClient($illegal_message);
            return OptConst::NO_RETURN;
        }

        //获取玩家当前状态，是否未准备
        $rStatus = $this->queryAccountStatus($room_id, $account_id);
        if(RedisConst::DATA_NONEXISTENT === $rStatus || !in_array($rStatus, [Game::AccountStatus_Initial, Game::AccountStatus_Notready])  )
        {
            $this->writeLog("function(readyStart):account($account_id) status($rStatus) invalid"." in file".__FILE__." on Line ".__LINE__);
            return array("result"=>OptConst::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"状态异常");
        }

        //更新用户状态
        $rStatus = Game::AccountStatus_Ready;
        $this->updateAccountStatus($room_id, $account_id, $rStatus);

        $this->startGame($room_id);

        return OptConst::NO_RETURN;
    }

    /*
        取消准备操作
    */
    public function readyCancel($arrData)
    {
        $timestamp = time();
        $result = array();
        $return = array();

        $data           = $arrData['data'];
        $operation      = $arrData['operation'];
        $account_id     = $arrData['account_id'];
        $client_id      = $arrData['client_id'];

        $session        = $arrData['session'];

        if(false == Verificate::getInstance()->checkRequestSession($account_id,$session))
        {
            return OptConst::NO_RETURN;
        }

        if(!isset($data['room_id']) || trim($data['room_id']) == GlobalConst::EMPTY_STRING)
        {
            $this->logMessage('error', "function(readyCancel):lack of room_id"." in file".__FILE__." on Line ".__LINE__);
            return $this->_missingPrameterArr($operation,"room_id");
        }

        $room_id = $data['room_id'];

        //设置当前状态，已准备
        //更新用户状态
        $rStatus = Game::AccountStatus_Notready;
        $this->updateAccountStatus($room_id, $account_id, $rStatus);

        $ready_count = $this->queryReadyCount($room_id);
        if($ready_count < 2){
            //取消倒计时
            $this->deleteRoomTimer($room_id);
            $arr = array("result"=>0,"operation"=>"CancelStartLimitTime","data"=>array(),"result_message"=>"取消开局倒计时");
            $this->pushMessageToGroup($room_id, $arr);
        }

        return OptConst::NO_RETURN;
    }

    /*
        历史积分榜
    */
    public function historyScoreboard($arrData)
    {
        $result = array();

        $data           = $arrData['data'];
        $operation      = $arrData['operation'];
        $account_id     = $arrData['account_id'];
        $client_id      = $arrData['client_id'];

        $session        = $arrData['session'];

        if(false == Verificate::getInstance()->checkRequestSession($account_id,$session)) {
            return OptConst::NO_RETURN;
        }

        if(isset($room_number) && $room_number > 0 ) {
            //判断房间申请记录是否存在
            $room_info = $this->getRoomByRoomNumber($room_number);
            if(!is_array($room_info) || count($room_info) == 0 ) {
                $this->writeLog("function(lastScoreboard):room(".$room_number.") not exist"." in file".__FILE__." on Line ".__LINE__);
                return array("result"=>OptConst::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"房间不存在");
            }else{
                $room_id = $room_info[0]['room_id'];
            }
        } else if(isset($data['room_id'])&& $data['room_id'] > 0) {
            $room_id = $data['room_id'];
        } else {
            $this->logMessage('error', "function(historyScoreboard):lack of room_id"." in file".__FILE__." on Line ".__LINE__);
            return $this->_missingPrameterArr($operation,"room_id");
        }

        $scoreboards = array();
        $query = $this->getRoomScoreboardByRoomID($room_id);
        if(!is_array($query) ){
            $this->writeLog("function(historyScoreboard):room($room_id) not exist"." in file".__FILE__." on Line ".__LINE__);
            //return array("result"=>OptConst::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"没积分榜");
        }else{
            foreach ($query as $row) {

                $name_board = array();
                $scoreboard = json_decode($row['board']);
                $create_time = $row['create_time'];

                if($scoreboard){
                    foreach ($scoreboard as $account_id => $score) {
                        $name = $this->getAccountNickName($account_id);
                        $name_board[] = array('name'=>$name, 'score'=>$score);
                    }
                    $scoreboards[] = array('time'=>$create_time, 'scoreboard'=>$name_board);
                }
            }
        }
        return array("result"=>"0","operation"=>$operation,"data"=>$scoreboards,"result_message"=>"历史积分榜");
    }

    /**
     * 最后一局积分榜
     * @param $arrData
     * @return array|int
     */
    public function lastScoreboard($arrData){
        $result = array();

        $data           = $arrData['data'];
        $operation      = $arrData['operation'];
        $account_id     = $arrData['account_id'];
        $client_id      = $arrData['client_id'];

        $session        = $arrData['session'];

        if(false == Verificate::getInstance()->checkRequestSession($account_id,$session))
        {
            return OptConst::NO_RETURN;
        }

        if(!(isset($room_number)&& $room_number > 0) )
        {
            $this->logMessage('error', "function(lastScoreboard):lack of room_number"." in file".__FILE__." on Line ".__LINE__);
            return $this->_missingPrameterArr($operation,"room_number");
        }

        $room_number = $room_number;
        //判断房间申请记录是否存在
        $room_info = $this->getRoomByRoomNumber($room_number);
        if(!is_array($room_info) || count($room_info) == 0 )
        {
            $this->writeLog("function(lastScoreboard):room($room_number) not exist"." in file".__FILE__." on Line ".__LINE__);
            return array("result"=>OptConst::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"房间不存在");
        }else{
            $room_id = $room_info[0]['room_id'];
        }

        $scoreboards = new \stdClass();
        $query = $this->getRoomScoreboardByRoomID($room_id);
        if(!is_array($query) ) {
            $this->writeLog("function(lastScoreboard):room($room_id) not exist"." in file".__FILE__." on Line ".__LINE__);
        }else{
            foreach ($query as $row) {

                $name_board = array();
                $scoreboard = json_decode($row['board']);
                $create_time = $row['create_time'];
                $game_num = $row['game_num'];

                $total_num = "";
                $rule_text = $row['rule_text'];
                $rule_text_array = explode('局/',$rule_text);
                if(is_array($rule_text_array) && count($rule_text_array) > 0)
                {
                    $total_num = $rule_text_array[0];
                }

                if($scoreboard){
                    foreach ($scoreboard as $account_id => $score) {
                        $name = $this->getAccountNickName($account_id);
                        $name_board[] = array('name'=>$name, 'score'=>$score, 'account_id'=>$account_id);
                    }
                    $scoreboards = array('time'=>$create_time, 'scoreboard'=>$name_board,'game_num'=>$game_num,'total_num'=>$total_num);
                }
            }
        }

        return array("result"=>"0","operation"=>$operation,"data"=>$scoreboards,"result_message"=>"历史积分榜");
    }
    public function closeRoom($arrData)
    {
        $operation = $arrData['operation'];
        $data = $arrData['data'];
        $account_id = $arrData['account_id'];
        $room_number = $room_number;



        // $current_timer_id = $this->queryTimerId($room_id);
        // if($current_timer_id == $timer_id){
        //  $this->updateTimer($room_id, -1);
        // } else {
        //  //timer对不上，返回
        //  $this->writeLog("function(clearRoomPassive):timer对不上($current_timer_id != $timer_id)"." in file".__FILE__." on Line ".__LINE__);
        //  return false;
        // }

        //判断是否全部人离线
        //$clients_of_groupid = Gateway::getClientSessionsByGroup($room_id);
        //if(count($clients_of_groupid) > 0){
        //    $this->writeLog("function(clearRoomPassive):房间($room_id)有人不清理");
        //    return false;
        //}

        $room_info = $this->getRoomByRoomNumber($room_number, 0);
        if(!is_array($room_info) || count($room_info) == 0 )
        {
            $this->writeLog("function(closeRoomManager):room($room_number) not exist"." in file".__FILE__." on Line ".__LINE__);
            return array("result"=>OptConst::FAILED,"operation"=>$operation,"data"=>[],"result_message"=>"房间不存在");
        }else{
            $room_id = $room_info[0]['room_id'];
        }

        if ($room_info[0]['account_id'] != $account_id){
            $this->writeLog("function(closeRoomManager):room($room_number) no auth"." in file".__FILE__." on Line ".__LINE__);
            return array("result"=>OptConst::FAILED,"operation"=>$operation,"data"=>[],"result_message"=>"不是管理员，不能关闭房间");
        }

        $this->writeLog("[$room_id] 触发群主清房间");

        $game_num = $this->queryGameNumber($room_id);
        $creator = $this->queryCreator($room_id);
        if(Config::Ticket_Mode==2 && $game_num==0 && $creator>0){
            $spend_ticket_count = $this->queryTicketCount($room_id);
            $this->balanceTicket($room_id, $creator, - $spend_ticket_count);
        }

        //保存积分榜
        if($game_num > 0){
            $round = $this->hincrbyRoomKey($room_id, RedisConst::Room_Field_GameRound, 1);
            $this->writeLog("[$room_id] 第".($round-1)."轮 结束!");

            $setting = $this->queryRoomKey($room_id);
            //$round = $setting['ground'];
            $game_info['room_id'] = $room_id;
            $game_info['game_type'] = Game::Game_Type;
            $game_info['dealer_num'] = Config::Dealer_Num;
            $game_info['round'] = $round-1;

            $scoreboard = array();
            if(isset($setting['scoreboard']) && $setting['scoreboard']){
                $board_json_str = $setting['scoreboard'];
                $scoreboard = json_decode($board_json_str, true); //转为关联数组
            } else {
                //积分榜为空
                $scoreboard = array();
                $board_json_str = "";
            }
            $name_board = array();
            foreach ($scoreboard as $account_id => $score) {
                $name = $this->getAccountNickName($account_id);
                $name_board[] = array('name'=>$name, 'score'=>$score, 'account_id'=>$account_id);
            }

            //规则文本
            $rule_text = $this->formatRuleText($room_id);
            $balance_scoreboard = array('time'=>time(), 'scoreboard'=>$name_board,'game_num'=>$game_num);
            $balance_board_json_str = json_encode($balance_scoreboard['scoreboard']);

            $start_time = $this->queryStartTime($room_id);

            $board_array['start_time'] = $start_time;
            $board_array['create_time'] = time();
            $board_array['is_delete'] = GlobalConst::IS_FALSE;
            $board_array['game_type'] = Game::Game_Type;
            $board_array['room_id'] = $room_id;
            $board_array['round'] = $round - 1;
            $board_array['game_num'] = $game_num;
            $board_array['rule_text'] = $rule_text;
            $board_array['board'] = $board_json_str;
            $board_array['balance_board'] = $balance_board_json_str;
            $this->insertRoomScoreboard($board_array);
            //保存用户积分
            $game_info['score_board'] = $scoreboard;
            $this->saveAccountGameScore($game_info);
        }
        $client_list = Gateway::getClientInfoByGroup($room_id);
//        var_dump($client_list);
        foreach ($client_list as $client_id=>$item) {
            Gateway::closeClient($client_id);
        }
        //清理房间
        $this->clearRoom($room_id);

        return true;
    }
}
